﻿using LinkedInApi;
using System;
using System.IO;
using System.Linq;

namespace LinkedInApiTester
{
    class Program
    {
        private static ILogger logger;

        static int Main(string[] args)
        {
            logger = ApiClient.CreateConsoleLogger();

            logger.Log(String.Format("{0} v.{1}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version));

            var api = new ApiClient(logger);

            AccessToken atoken = ReadATokenFromFile();

            if (atoken == null || !atoken.IsValid)
            {
                logger.Log(atoken != null ? "Access Token is expired on " + atoken.ExpireDate.ToString("o") + ". Request new token" : "Request new token");
                atoken = api.GetAccessToken(Properties.Settings.Default.ClientID,
                    Properties.Settings.Default.SecretKey,
                    Properties.Settings.Default.OAuth2CallbackUrl,
                    Properties.Settings.Default.Login,
                    Properties.Settings.Default.Password,
                    null,
                    Properties.Settings.Default.Timeout).Result;

                if (api.HasErrors)
                {
                    logger.Log(api.GetLastError().ToString());
                    return -1;
                }
                else if (atoken == null || !atoken.IsValid)
                    return -2;

                WriteATokenToFile(atoken);
            }

            logger.Log("Request Basic Profile Fields");
            var fld = new string[] { "id", "first-name", "last-name", "headline", "picture-url", "public-profile-url" };

            var data = api.GetBasicProfileFields(atoken, fld).Result;

            if (api.HasErrors)
            {
                logger.Log(api.GetLastError().ToString());
                return -3;
            }

            logger.Log("Data received, saving result");

            try
            {
                File.WriteAllLines(Properties.Settings.Default.OutputFilePath,
                    data.Select(row => String.Join(";", row)), System.Text.Encoding.UTF8);

                logger.Log("Data saved successful");
                return 0;
            }
            catch (Exception e)
            {
                logger.Log(e);
                return -4;
            }
        }

        private static AccessToken ReadATokenFromFile()
        {
            logger.Log("ReadATokenFromFile()");
            var filename = Properties.Settings.Default.AccessTokenFileName;
            if (File.Exists(filename))
            {
                logger.Log("ReadATokenFromFile()", "Read file {0}", filename);
                try
                {
                    var data = File.ReadAllBytes(filename);
                    logger.Log("ReadATokenFromFile()", "Reeded {0} bytes, decrypt data to Access Token", data.Length);

                    return AccessToken.Decrypt(data, Properties.Settings.Default.Login);
                }
                catch (Exception e)
                {
                    logger.Log("ReadATokenFromFile()", e);
                }
            }
            else
                logger.Log("ReadATokenFromFile()", "File {0} not found", filename);

            return null;
        }

        private static void WriteATokenToFile(AccessToken atoken)
        {
            logger.Log("WriteATokenToFile()");
            var filename = Properties.Settings.Default.AccessTokenFileName;

            try
            {
                logger.Log("WriteATokenToFile()", "Encrypt Access Token data");
                var data = atoken.Encrypt(Properties.Settings.Default.Login, logger);

                logger.Log("WriteATokenToFile()", "Write {0} bytes to file {1}", data.Length, filename);

                File.WriteAllBytes(filename, data);

                logger.Log("WriteATokenToFile()", "Write successful");
            }
            catch (Exception e)
            {
                logger.Log("WriteATokenToFile()", e);
            }
        }
    }
}
